﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;


namespace OrganizedConfusion
{
    public class TestState : GameState
    {
        int Image;
        int inputWord;
        List<DisplayMode> Modes = new List<DisplayMode>();
            
        public string THIS_IS_A_WTF = "Whats up homie";

        List<string> scores = new List<string>();

        public TestState()
        {
            Modes.Clear();
        }

        static void go()
        {
            object obj = new object();

            lock(obj)
                Console.Write((24 * 6 / 12 + 32 * 100000 % 6 / 2 + 300674 * 90) + '\n');
        }

        public override void LoadContent()
        {
            base.LoadContent();
            object syncObj = new object();
            //lock (syncObj)
            //{
            //    new Thread(() => SaveXML("test2.xml")).Start();
            //}
            //lock (syncObj)
            //{
            //    new Thread(() => LoadXML("test2.xml")).Start();
            //}
            lock (syncObj)
            {
                new Thread(() => SaveBinary("testObjects.bin")).Start();
            }
            //lock (syncObj)
            //{
            //    new Thread(() => LoadBinary("testBin.bin")).Start();
            //}
            //SaveXML("test2.xml");
            //LoadXML("test2.xml");

            //SaveBinary("testBin.bin");
            //if (!LoadBinary("testBin.bin"))
            //    Console.Write("Failed to load in binary file, Try again dude.");

            //Image = Contentmanager.Load<Texture2D>("Textures/test1");
            Image = ContentsManager.Instance.LoadTexture("Textures/test1");
            Inputmanager.AcquireKeyboard(Keyboard.GetState());
            Inputmanager.AcquireGamePad(GamePad.GetState(PlayerIndex.One));
        }

        static void SaveXML(string asset)
        {
            //while (!xReader.EOF)
            //{
            //    scores.Add(xReader.GetAttribute("score"));
            //}
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "    ";
            settings.NewLineOnAttributes = false;
            //StreamReader sR = new StreamReader("OrderDetails.xml");
            StreamWriter sW = new StreamWriter(asset);
            XmlWriter xWriter = XmlWriter.Create(sW, settings);

            if (xWriter != null)
                Console.Write("I was able to write\n");

            xWriter.WriteComment("This is a test comment");
            xWriter.WriteStartElement("OrderDetails");
            xWriter.WriteStartElement("Order");
            xWriter.WriteAttributeString("OrderID", "001");
            xWriter.WriteElementString("ProductName", "ASP.NET2.0");
            xWriter.WriteElementString("Price", "0");
            xWriter.WriteEndElement();
            xWriter.WriteStartElement("Order");
            xWriter.WriteAttributeString("OrderID", "O002");
            xWriter.WriteElementString("ProductName", "Mono-Develop-SDK");
            xWriter.WriteElementString("Price", "0");
            xWriter.WriteEndElement();
            xWriter.WriteEndElement();
            xWriter.Flush();
            xWriter.Close();
            Console.Write("Success on XML save\n");
        }

        static void LoadXML(string asset)
        {
            XElement xRoot = XElement.Load(asset);
            if (xRoot != null)
                Console.Write("I was able to read.\n");
            else
                return;

            IEnumerable<XElement> xOrders = xRoot.Elements();

            foreach (XElement Order in xOrders)
            {
                Console.Write(Order.Attribute("OrderID").Value + '\n');
                Console.Write(Order.Element("ProductName").Value + '\n');
                Console.Write(Order.Element("Price").Value + "\n\n");
            }
            Console.Write("Success on XML load\n");
        }

        static bool LoadBinary(string asset)
        {
            if (File.Exists(asset))
            {
                BinaryReader bReader = new BinaryReader(File.Open(asset, FileMode.Open));

                try
                {
                    // If the file is not empty,
                    // read the application settings.
                    // First read 4 bytes into a buffer to
                    // determine if the file is empty.
                    byte[] testArray = new byte[3];
                    int count = bReader.Read(testArray, 0, 3);

                    // Reset the position in the stream to zero.
                    bReader.BaseStream.Seek(0, SeekOrigin.Begin);

                    int loopAmount = bReader.ReadInt32();

                    for (int i = 0; i < loopAmount; i++)
                    {
                        Console.Write(bReader.ReadInt32().ToString() + '\n');
                        Console.Write(bReader.ReadString().ToString() + '\n');
                        Console.Write(bReader.ReadInt32().ToString() + "\n\n");
                    }
                }
                catch (EndOfStreamException e)
                {
                    Console.WriteLine("{0} caught and ignored. " +
                        "Using default values.", e.GetType().Name);
                }
                finally
                {
                    bReader.Close();
                }
                Console.Write("Success on binary load\n");
                return true;
            }
            else
                return false;
        }

        static void SaveBinary(string asset)
        {
            BinaryWriter bWriter = new BinaryWriter(File.Open(asset, FileMode.Create));
            {
                int loop = 1000;
                int players = 2;
                bWriter.Write(loop + players + 1);// number of times to loop
                for (int i = 0; i < players; i++)
                {
                    bWriter.Write(8);
                    bWriter.Write(340);
                    bWriter.Write(350);
                }
                for (int i = 0; i < loop; i++)
                {
                    bWriter.Write(2);
                    bWriter.Write(300 + (i * 173));
                    bWriter.Write(360);
                }
                bWriter.Write(1);
                bWriter.Write(4000);
                bWriter.Write(250);
                //bWriter.Write(512);
                //bWriter.Write("Working on the second!");
                //bWriter.Write(64);

                bWriter.Flush();
                bWriter.Close();
                Console.Write("Success on binary save\n");
            }
        }

        public override void Input()
        {
            if (Inputmanager.KeyPressedBuffered(Keys.A) || Inputmanager.ButtonPressedBuffered(Buttons.LeftThumbstickDown))
                inputWord++;

            if (Inputmanager.ButtonHeldDown(Buttons.LeftThumbstickLeft))
                inputWord--;

            if (Inputmanager.KeyPressedBuffered(Keys.Space) || Inputmanager.ButtonPressedBuffered(Buttons.Start))
                Statemanager.Changestate(new Intro());

            if (Inputmanager.KeyPressedBuffered(Keys.S))
                Statemanager.AddState(new Intro());

            if (Inputmanager.KeyPressedBuffered(Keys.D) || Inputmanager.ButtonPressedBuffered(Buttons.A))
            {
                foreach (DisplayMode displayMode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
                {
                    if(displayMode.Format.ToString().Equals("Color"))
                        Modes.Add(displayMode);
                }
            }

            if(Inputmanager.KeyPressedBuffered(Keys.Escape) || Inputmanager.ButtonPressedBuffered(Buttons.Back))
                Statemanager.EndGame();
        }

        public override void Update(GameTime gameTime)
        {
            Input();

            //if ((int)(gameTime.TotalGameTime.TotalSeconds % 2) == 0)
            //{
            //    object obj = new object();

            //    lock(obj)
            //        new Thread(go).Start();
            //}
        }

        public override void Render(GameTime gameTime)
        {
            SpriteBatch spriteBatch = Statemanager.Spritebatch;
            Viewport viewport = Statemanager.GraphicsDevice.Viewport;
            Rectangle TestRect = new Rectangle(0, 0, 720, 540);
            Rectangle FullScreen = new Rectangle(28, 26, 740, 552);
            Rectangle sourceRect = new Rectangle(0, 0, 708, 522);

            spriteBatch.Begin();
            //spriteBatch.Draw(Image, FullScreen, sourceRect, Color.White);
            //spriteBatch.Draw(Image, TestRect, sourceRect, Color.White);
            spriteBatch.Draw(ContentsManager.Instance.Draw(Image), TestRect, sourceRect, Color.White);

            float frameRate = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;

            for(int i = 0; i < scores.Count; i++)
                spriteBatch.DrawString(Statemanager.Font, scores[i], new Vector2(200, 10*i), Color.Violet);

            spriteBatch.DrawString(Statemanager.Font, frameRate.ToString() + " FPS", new Vector2(400, 100), Color.Violet);
            spriteBatch.DrawString(Statemanager.Font, GamePad.GetState(0).DPad.Down.ToString(), new Vector2(400, 300), Color.Violet);
            spriteBatch.DrawString(Statemanager.Font, "Test State", new Vector2(400, 240), Color.Violet);
            spriteBatch.DrawString(Statemanager.Font, inputWord.ToString(), new Vector2(400, 200), Color.Violet);

            if(Modes.Count > 0)
            {
                int index = 0;
                int pos = 50;
                foreach( DisplayMode dm in Modes)
                    spriteBatch.DrawString(Statemanager.Font, Modes[index++].ToString(), new Vector2(100, pos += 20), Color.White);
            }

            spriteBatch.End();

            //base.Render(gameTime);
        }
    }
}
